from django.db import models
from django.contrib.auth import models as auth_models
from datetime import datetime, date

import unittest
import logging

from django.db import models

logger = logging.getLogger(__name__)

class Customer(models.Model):
    name = models.CharField(max_length=50)

    def __str__ (self):
        return 'Customer (name=' + name + ')'

class Client(models.Model):
    name = models.CharField(max_length=50)
    vat = models.CharField(max_length=13, default='')

    def __str__ (self):
        return 'Client (name=' + self.name + ', vat=' + self.vat + ')'

class Address(models.Model):
    street = models.CharField(max_length=60)
    zip = models.CharField(max_length=10)
    city = models.CharField(max_length=20)
    country = models.CharField(max_length=20)

    def __str__ (self):
        return 'Address (street=' + self.street + ', zip=' + self.zip + ', city=' + self.city + ', country=' + self.country + ')'


class ClientAddressLink(models.Model):
    client = models.ForeignKey(Client)
    address = models.ForeignKey(Address)
    since = models.DateField()

class Invoice(models.Model):
    number = models.CharField(max_length=7)
    date = models.DateField(auto_now=True)
    client = models.ForeignKey(Client)

    def __str__ (self):
        return 'Invoice (number=' + self.number + ', date=' + self.date.strftime('%d/%m/%Y') + ', client=' + self.client.name + ')'

class InvoiceLine(models.Model):
    invoice = models.ForeignKey(Invoice)
    description = models.CharField(max_length=70)
    quantity = models.DecimalField(max_digits=7, decimal_places=2)
    unit_price = models.DecimalField(max_digits=10, decimal_places=2)
    vat = models.DecimalField(max_digits=4, decimal_places=2)

    def __str__ (self):
        return 'Invoice Line (invoice=' + self.invoice.number + ', description=' + self.description + ', quantity=' + self.quantity + ', unit_price=' + self.unit_price + ', vat=' + self.vat + ')'

class Day(models.Model):
    date = models.DateField()
    worked_hours = models.IntegerField(default=0)
    timesheet = models.ForeignKey('Timesheet')

    def __str__ (self):
        return 'Day (date=' + self.date.strftime('%d/%m/%Y') + ', worked_hours=' + self.worked_hours + ', timesheet=' + self.timesheet.id + ')'


class Timesheet(models.Model):
    customer = models.ForeignKey(Customer, null=True)
    manager = models.CharField(max_length=75)
    project = models.CharField(max_length=50)
    user = models.ForeignKey(auth_models.User)
    contract = models.ForeignKey('Contract')

    def buildTimesheetName(self):
        if len(self.day_set.all()) < 10:
            logger.error("invalid timesheet with less then 10 days. Timesheet id is " + self.id)
        monthAndYear = list(self.day_set.all())[9].date.strftime('%m/%Y')
        try:
            return self.contract.name + ' - ' + monthAndYear
        except:
            return self.customer.name + ' - ' + monthAndYear

    def getTotalHours(self):
        worked_hours = 0
        for day in self.day_set.all():
          worked_hours += day.worked_hours
        return worked_hours

    def __str__ (self):
        logstring = 'Timesheet ('
        logstring = logstring + 'customer=' + self.getName()
        logstring = logstring + ', manager=' + self.manager
        logstring = logstring + ', project=' + self.project
        try:
            user_name = self.user.username
        except Exception, e:
            user_name = "not set"
        logstring = logstring + ', user=' + user_name
        logstring = logstring + ', worked_hours='
        logstring = logstring + str(self.getTotalHours())
        try:
            contract_name = self.contract.name
        except Contract.DoesNotExist:
            contract_name = 'None'
        logstring = logstring + ', contract=' + contract_name
        logstring = logstring + ')'
        return logstring

    def getName(self):
        try:
            return self.contract.customer.name
        except Contract.DoesNotExist:
            return self.customer.name

    def getContract(self):
        try:
            return self.contract
        except Contract.DoesNotExist:
            return None

class Holiday(models.Model):
    date = models.DateTimeField()
    description = models.CharField(max_length=100)

    def __str__ (self):
        return 'Holiday (date=' + self.date.strftime('%d/%m/%Y') + ', description=' + self.description + ')'

class Contract(models.Model):
    name = models.CharField(max_length=50)
    start = models.DateField()
    end = models.DateField()
    client = models.ForeignKey(Client)
    customer = models.ForeignKey(Customer)
    email_for_invoice = models.CharField(max_length=50)
    hourly_rate = models.FloatField()

    def __str__ (self):
        return 'Contract (name=' + self.name + ', start=' + self.start.strftime('%d/%m/%Y') + ', end=' + self.end.strftime('%d/%m/%Y') + ', client='+ self.client.name + ', customer=' + self.customer.name + ', email=' + self.email_for_invoice + ', hourly rate=' + str(self.hourly_rate) + ')'


class TimesheetTest(unittest.TestCase):
    def test_buildTimesheetName(self):
        contract = Contract.objects.create(name='contract_007',start=date(2012,03,1), end=date(2012,9,15), client_id=1, customer_id=1, hourly_rate=63.75)
        timesheet = Timesheet.objects.create(contract=contract, user_id=1, id=1000)
        for i in range(1,31):
            timesheet.day_set.add(Day.objects.create(id=i+1000, date=date(2012,03,i), timesheet_id=1))
        self.assertEqual('contract_007 - 03/2012', timesheet.buildTimesheetName())